ChatGPTと一緒にサーバーを立ててみる
ChatGPTとは
ChatGPTは対話に最適化されてた深層学習のモデルの一つです。 OpenAIによってChatGPTとWebページ上でやり取りを行うことができます。
ChatGPTの詳細については以下の記事が参考になると思います。
対話の内容は汎用的で、一般的な会話からコードの生成までできたりします。 今回はChatGPTと一緒にEC2の構築を行おうと思いますが、一応以下のような普通の会話もできます。
今回構築したいもの
ChatGPTは一度にあまり長いコードは生成できないみたいなので、シンプルなアーキテクチャを構築します。
VPC内にEC2が1台あってそこにNginxがインストールされているというものです。 構成図でいうと以下のような感じです。
一緒に構築すると言ってもChatGPTがAWS環境を直接触れるわけではないので、今回はCloudFormationのコードを生成してもらいます。 自分は生成されたコードをレビューしながらデプロイしていきます。
ChatGPTにお願いしてみる。
VPC作成
まずはジャブがてらVPCを作成するテンプレートを生成してもらいましょう。
指定したCIDRはなどのパラメータはしっかりと反映されています。 ですが、インターネットへの経路が設定されていません。 再度お願いしてみます。
いい感じです。 ルートテーブルも明示的に設定してもらいます。
悪くないんじゃないでしょうか? Exportしてる部分が気になりますが、しっかりと変数名にスタック名でプレフィックスを入れてくれているので問題なさそうです。 リソース名などもいいと思います。
一度、この状態でデプロイしてみます。
問題なくデプロイできました。
EC2を追加してもらう
EC2を追加してNginxもインストールしてもらいます。
いい感じです。 コードが長くなったので生成してもらったものは付録に書いておきます。 追加された部分は以下のコードです。
EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-09d95fab7fff3776c InstanceType: t2.micro KeyName: sample-key SecurityGroupIds: - !Ref InstanceSecurityGroup SubnetId: !Ref PublicSubnet UserData: "Fn::Base64": !Sub | #!/bin/bash yum update -y yum install -y nginx systemctl start nginx systemctl enable nginx InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for EC2 instance VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0
セキュリティグループまでしっかり作成してくれています。 流石ですね。
AMIの正体
まず気になるのはAMIです。 せっかくなので、ChatGPTにAMIの詳細をCLIから取得する方法を聞いてみます。
それっぽいコマンドを出力してくれました。 CLIのリファレンスを確認してみると適切なコマンドです。
実行してみましたが、該当のイメージはないとのことです。
$ aws ec2 describe-images --image-ids ami-09d95fab7fff3776c An error occurred (InvalidAMIID.NotFound) when calling the DescribeImages operation: The image id '[ami-09d95fab7fff3776c]' does not exist
AMIの部分は適当なAL2の最新のAMIにこちらで変更します。
ユーザーデータの中身
AmazonLinux2だとNginxはamazon-linux-extrasを使用してインストールすることが多いかなと思います。 このままのコードだとamazon-linux-extrasを使用するように警告が出てNginxのインストールが失敗します。
ChatGPTにamazon-linux-extrasを使用してインストールするように変更してもらいます。
コード全体の変更は出力されてませんでしたが、ユーザーデータは出力されました。 これなら問題なさそうです。
デプロイしてみる
実際にこのテンプレートをデプロイしてみます。 詳細なコードについては付録に書いておきます。
シンタックスエラー等の問題もなく一発でデプロイできました。
HTTPで疎通確認してみる
ブラウザから該当のEC2にアクセスしてみます。
問題なくNginxのページが表示されました。
感想
ChatGPTすごいですね。一応汎用的な対話モデルとして作られているのにここまでコードの出力が自然にできるとは思っていませんでした。 特に前の会話を覚えていて、それを踏まえて修正してくれるところがすごいですね。
ただ、ChatGPTが生成したコードを何も考えずにそのまま使うのは危ないと思います。ChatGPTが必ずしも設計上のベストプラクティス、セキュリティやライセンスを考慮してくれるわけではないので) AWSの知識を持った上で生成されたコードをレビューしながら作業していく必要があると感じました。
ただ、対話的にコードを生成してくれるので誰かにお願いしながら一緒に作業をしている感覚はありました。 カスタマイズ性が高くインタラクティブなコードスニペットみたいな感じで向き合っていくと良いと思いました。
付録
ChatGPTが生成したテンプレート
AWSTemplateFormatVersion: '2010-09-09' Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true InternetGateway: Type: AWS::EC2::InternetGateway VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway PublicSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/24 MapPublicIpOnLaunch: true RouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PublicRoute: Type: AWS::EC2::Route DependsOn: VPCGatewayAttachment Properties: RouteTableId: !Ref RouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTable SubnetId: !Ref PublicSubnet EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-09d95fab7fff3776c InstanceType: t2.micro KeyName: sample-key SecurityGroupIds: - !Ref InstanceSecurityGroup SubnetId: !Ref PublicSubnet UserData: "Fn::Base64": !Sub | #!/bin/bash yum update -y yum install -y nginx systemctl start nginx systemctl enable nginx InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for EC2 instance VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 Outputs: VPCID: Description: VPC ID Value: !Ref VPC Export: Name: !Sub '${AWS::StackName}-VPCID' PublicSubnetID: Description: Public Subnet ID Value: !Ref PublicSubnet Export: Name: !Sub '${AWS::StackName}-PublicSubnetID' EC2InstanceID: Description: EC2 instance ID Value: !Ref EC2Instance Export: Name: !Sub '${AWS::StackName}-EC2InstanceID'
修正したもの
AWSTemplateFormatVersion: '2010-09-09' Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true InternetGateway: Type: AWS::EC2::InternetGateway VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway PublicSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.0.0/24 MapPublicIpOnLaunch: true RouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PublicRoute: Type: AWS::EC2::Route DependsOn: VPCGatewayAttachment Properties: RouteTableId: !Ref RouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTable SubnetId: !Ref PublicSubnet EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-072bfb8ae2c884cc4 InstanceType: t2.micro KeyName: sample SecurityGroupIds: - !Ref InstanceSecurityGroup SubnetId: !Ref PublicSubnet UserData: "Fn::Base64": !Sub | #!/bin/bash yum update -y amazon-linux-extras install -y nginx1 systemctl start nginx systemctl enable nginx InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for EC2 instance VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: 0.0.0.0/0 Outputs: VPCID: Description: VPC ID Value: !Ref VPC Export: Name: !Sub '${AWS::StackName}-VPCID' PublicSubnetID: Description: Public Subnet ID Value: !Ref PublicSubnet Export: Name: !Sub '${AWS::StackName}-PublicSubnetID' EC2InstanceID: Description: EC2 instance ID Value: !Ref EC2Instance Export: Name: !Sub '${AWS::StackName}-EC2InstanceID'